package cn.xzzz2020.XJynWeb.aop;

import org.aspectj.weaver.tools.PointcutExpression;
import org.aspectj.weaver.tools.PointcutParser;
import org.aspectj.weaver.tools.ShadowMatch;

import java.lang.reflect.Method;

/**
 * 解析Aspect表达式并定位被织入目标
 * @author xzzz2020
 * @version 1.0
 * @date 2020/8/12 17:30
 */
public class PointcutLocator {
    //表达式解析器，判断类和方法是否符合表达式
    private PointcutExpression pointcutExpression;

      public PointcutLocator(String expression){
        //Pointcut解析器,支持所有AspectJ的所有语法树，解析String类型的Pointcut语法
        PointcutParser pointcutParser = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingContextClassloaderForResolution(
                PointcutParser.getAllSupportedPointcutPrimitives()
        );
        this.pointcutExpression = pointcutParser.parsePointcutExpression(expression);
    }

    /**
     * 判断传入的Class对象是否符合Pointcut表达式（初筛）
     * @param targetClass 目标类
     * @return 是否匹配
     */
    public boolean roughMatches(Class<?> targetClass){
        //只能校验within的表达式，其他的都会表达true
        return pointcutExpression.couldMatchJoinPointsInType(targetClass);
    }

    /**
     * 判断传入的Method对象是否符合Pointcut表达式（精确筛选）
     * @param method 目标方法
     * @return 是否匹配
     */
    public boolean accurateMatches(Method method){
        ShadowMatch shadowMatch = pointcutExpression.matchesMethodExecution(method);
        //判断是否完全匹配
        return shadowMatch.alwaysMatches();
    }
}
